package cn.tedu.charging.cost.repository.impl;

import cn.tedu.charging.common.pojo.po.ChargingCostRulePO;
import cn.tedu.charging.cost.mapper.CostRuleMapper;
import cn.tedu.charging.cost.repository.CostRuleRepository;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.stream.Collectors;

@Repository
@Slf4j
public class CostRuleRepositoryImpl implements CostRuleRepository {
    @Autowired
    private CostRuleMapper costRuleMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public ChargingCostRulePO getCostRule(Integer stationId, Integer hour) {
        //当前的入参 应该大概率是 stationId=5 hour=19 查询计价规则
        //1.直接读取数据库
        //方案1: 利用时间 利用场站id组织查询sql select * from charging_cost_rule
        //where station_id=? and start_time<=? and end_time>?
        /*QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("station_id",stationId);
        queryWrapper.le("start_time",hour);
        queryWrapper.gt("end_time",hour);
        ChargingCostRulePO costRulePO = costRuleMapper.selectOne(queryWrapper);*/
        //方案2: 利用场站id 查询所有该场站的计价规则,然后使用hour做list列表的过滤筛选
        //select * from charging_cost_rule where station_id=?
        /*QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("station_id",stationId);
        List<ChargingCostRulePO> pos =costRuleMapper.selectList(queryWrapper);
        //循环便利这个pos集合中的每个元素,判断哪个元素起始时间,结束时间满足判断逻辑
        if (pos!=null&&pos.size()>0) {
            ChargingCostRulePO costRulePO = pos.stream().filter(po -> {
                //所有该场站的计价规则,都要经过这个条件筛选,满足则保留
                return po.getStartTime() <= hour && po.getEndTime() > hour;
            }).collect(Collectors.toList()).get(0);
            return costRulePO;
        }*/
        //2.利用cache-aside读流程 提升计价规则读取速度
        String costRuleKey="charging:cost:rules:"+stationId;
        //exists key
        Boolean exists = redisTemplate.hasKey(costRuleKey);
        List<ChargingCostRulePO> pos = null;
        if (exists){
            //计价规则命中缓存日志
            log.debug("计价规则命中缓存,stationId={},hour={}",stationId,hour);
            //直接使用缓存数据
            pos=redisTemplate.opsForList().range(costRuleKey,0,-1);
        }else{
            //没有命中缓存日志
            log.debug("计价规则未命中缓存,stationId={},hour={}",stationId,hour);
            QueryWrapper queryWrapper=new QueryWrapper();
            queryWrapper.eq("station_id",stationId);
            pos =costRuleMapper.selectList(queryWrapper);
            if (pos!=null&&pos.size()>0){
                //将查询到的pos集合中的元素 写入缓存中
                redisTemplate.opsForList().rightPushAll(costRuleKey,pos);
            }
        }
        //从pos中筛选一下满足小时数条件的元素
        if (pos!=null&&pos.size()>0){
            ChargingCostRulePO costRulePO = pos.stream().filter(po -> {
                //所有该场站的计价规则,都要经过这个条件筛选,满足则保留
                return po.getStartTime() <= hour && po.getEndTime() > hour;
            }).collect(Collectors.toList()).get(0);
            return costRulePO;
        }
        return null;
    }
}
